package com.tony.svn;

import com.tony.pojo.SvnInfo;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Create on 2018/11/12
 * @author tony
 */
public class SvnUtilTest {
    static final String QC_NO ="32073";
    static final int VERSION = 1;
    private static final String BEGIN_TIME = "2018-12-27";

    public static void main(String[] args) throws Exception {
        System.out.println("-------------start---------------");
        init("p2p");
        Map<String, SvnInfo> maps = filterCommitHistory();
        String targetFilePath = getTargetFile();
        List<SvnInfo> datas = new ArrayList<>();
        for(String key: maps.keySet()){
            datas.add(maps.get(key));
        }
        Collections.sort(datas, Comparator.comparing(SvnInfo::getPath));
        writeExcelData(targetFilePath,datas);
        System.out.println("-------------END---------------");
    }

    private static String SVNPATH = "";
    private static String url = "";
    private static String TEMPLATE_PATH = "src/main/resources/templates/svn.xls";
    private static SVNRepository repository = null;
    private static final String AUTHORS = "zhanglibin";
    static final String TARGET_URI ="D:\\工作\\打包";
    static String TARGET_MODEL ="";
    static final String TARGET_MATCHINE="测试机";
    private static final String USERNAME = "张利宾";
    static String svnVersion = "";

    static SimpleDateFormat simpleDateFormat = new SimpleDateFormat();

    static void init(String type) {
        if("p2p".equals(type)){
            SVNPATH = "Develop/projects/trunk/np2p/";
            url = "svn://svn.9fbank.com/np2p/"+SVNPATH;
            TARGET_MODEL ="P2P";
        }else if("bus".equals(type)){
            SVNPATH = "Develop/projects/7BUS loans in/branches/branches_dev/loaning-mircon/";
            url = "svn://svn.9fbank.com/BUS/"+SVNPATH;
            TARGET_MODEL ="bus";
        }else{
            System.exit(1);
        }

        DAVRepositoryFactory.setup();
        SVNRepositoryFactoryImpl.setup();
        FSRepositoryFactory.setup();
        try {
            repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(url));
        } catch (SVNException e) {
            e.printStackTrace();
        }
        // 身份验证
        ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager("zhanglibin", "zlnNe0we");
        repository.setAuthenticationManager(authManager);
    }

    public static Map<String, SvnInfo> filterCommitHistory() throws Exception {
        // 过滤条件
        final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        final long begin = format.parse(BEGIN_TIME).getTime();
        final Set<String> authorSet = new HashSet<>(Arrays.asList(AUTHORS.split(",")));
        long startRevision = 0;
        long endRevision = -1;
        final Map<String, SvnInfo> svnMaps = new HashMap<>();
        //String[] 为过滤的文件路径前缀，为空表示不进行过滤
        repository.log(new String[]{""},
                startRevision,
                endRevision,
                true,
                true,
                new ISVNLogEntryHandler() {
                    @Override
                    public void handleLogEntry(SVNLogEntry svnlogentry)
                            throws SVNException {
                        //依据提交时间进行过滤
                        if (authorSet.contains(svnlogentry.getAuthor())
                                && svnlogentry.getDate().getTime() >= begin) {
                            fillResult(svnlogentry);
                        }
                    }

                    public void fillResult(SVNLogEntry svnlogentry) {
                        Map<String, SVNLogEntryPath> map = svnlogentry.getChangedPaths();
                        SvnInfo svnInfo;
                        for (String key : map.keySet()) {
                            if(!key.contains(".")){
                                continue;
                            }
                            if(!"".equals(svnVersion)){
                                if(svnlogentry.getRevision()<=Long.parseLong(svnVersion)){
                                    continue;
                                }
                            }
                            String path = replacePath(map.get(key).getPath());
                            svnInfo = svnMaps.get(path);
                            if (svnInfo == null) {
                                svnInfo = new SvnInfo(getType(map.get(key).getType() + ""), path, getFileType(path));
                                svnInfo.setVersion(svnlogentry.getRevision());
                            } else {
                                svnInfo.setVersion(svnlogentry.getRevision());
                            }
                            svnMaps.put(path, svnInfo);
                        }
                    }
                });
        return svnMaps;
    }

    static String replacePath(String path) {
        return path.replace(SVNPATH, "");
    }

    static String getFileType(String res) {
        System.out.println(res);
        if (res.endsWith("java")) {
            return "JAVA";
        } else if (res.endsWith("xml")) {
            return "XML";
        } else if (res.endsWith("jsp")) {
            return "JSP";
        } else {
            return "";
        }
    }

    static String getType(String type) {
        if ("A".equals(type)) {
            return "增加";
        }
        if ("D".equals(type)) {
            return "删除";
        }
        if ("M".equals(type)) {
            return "修改";
        } else {
            return "增加";
        }
    }

    private static void writeExcelData(String targetFilePath,List<SvnInfo> datas) throws IOException, InvalidFormatException {
        HSSFWorkbook workbook = (HSSFWorkbook) WorkbookFactory.create(new File(TEMPLATE_PATH));
        HSSFSheet sheet = workbook.getSheetAt(0);
        CellStyle cellStyle = workbook.createCellStyle();
        HSSFDataFormat format= workbook.createDataFormat();
        cellStyle.setDataFormat(format.getFormat("yyyy/mm/dd HH:MM"));
        int r = 1;
        HSSFRow row;
        HSSFCell cell;
        for (SvnInfo svnInfo:datas){
            row = createRow(sheet,r);
            cell = createCell(row,0);
            cell.setCellValue(svnInfo.getType());
            cell = createCell(row,1);
            cell.setCellValue(svnInfo.getPath());
            cell = createCell(row,2);
            cell.setCellValue(svnInfo.getFileType());
            cell = createCell(row,3);
            cell.setCellValue(svnInfo.getVersion());
            cell = createCell(row,4);
            cell.setCellValue(QC_NO);
            cell = createCell(row,5);
            cell.setCellValue("");
            cell = createCell(row,6);
            cell.setCellValue("");
            cell = createCell(row,7);
            cell.setCellValue("无");
            cell = createCell(row,8);
            cell.setCellValue(USERNAME);
            cell = createCell(row,9);
            cell.setCellValue(new Date());
            cell.getCellStyle().setDataFormat(format.getFormat("yyyy/m/d h:mm"));

            r++;
        }
        FileOutputStream fos = new FileOutputStream(targetFilePath);
        workbook.write(fos);
    }

    private static HSSFCell createCell(HSSFRow row, int c) {
        HSSFCell cell = row.getCell(c);
        if(cell!=null){
            row.removeCell(cell);
        }
        return row.createCell(c);
    }

    private static HSSFRow createRow(HSSFSheet sheet, int r) {
        HSSFRow row = sheet.getRow(r);
        if(row!=null){
            sheet.removeRow(row);
        }
        return sheet.createRow(r);
    }

    public static String getTargetFile() throws IOException {
        simpleDateFormat.applyPattern("yyyyMMdd");
        String date = simpleDateFormat.format(new Date());
        String target = TARGET_URI+File.separator+TARGET_MODEL+File.separator+date;
        File fold = new File(target);
        if(!fold.exists()){
            fold.mkdirs();
        }
        String filename = TARGET_MATCHINE+"_"+USERNAME+"_QC"+QC_NO+"_CODE_提交单_"+date+ getVersion(VERSION)+".xls";
        return target+File.separator+filename;
    }

    private static String getVersion(int version) {
        return String.format("%03d", version);
    }

}
